﻿using Ndns.ServerHost.Abstractions.Features;
using System;
using System.Collections.Generic;
using System.Collections;
using System.Threading;

namespace Ndns.ServerHost.Features
{
    class FeatureCollection : IFeatureCollection
    {
        private readonly Dictionary<Type, object> _features;
        private readonly bool _isReadOnly;
        private int _revision;

        public FeatureCollection(IEnumerable<KeyValuePair<Type, object>> builtInFeatures, bool isReadOnly)
        {
            _features = new Dictionary<Type, object>();
            if (builtInFeatures != null)
            {
                foreach (var item in builtInFeatures)
                {
                    if (!_features.ContainsKey(item.Key))
                    {
                        // TODO 检查类型是否匹配
                        _features.Add(item.Key, item.Value);
                    }
                }
            }
            _isReadOnly = isReadOnly;
            _revision = 0;
        }


        public object this[Type key]
        {
            get => _features[key];
            set
            {
                if (_isReadOnly)
                    throw new InvalidOperationException();
                _features[key] = value;
                Interlocked.Increment(ref _revision);
            }
        }

        public bool IsReadOnly => _isReadOnly;

        public int Revision => throw new NotImplementedException();

        public TFeature Get<TFeature>()
        {
            try
            {
                if (_features.TryGetValue(typeof(TFeature), out var result))
                {
                    var castedResult = (TFeature)result;
                    return castedResult;
                }
            }
            catch (Exception)
            {
                // nop
            }
            return default(TFeature);
        }


        public void Set<TFeature>(TFeature instance)
        {
            if (_isReadOnly)
            {
                throw new InvalidOperationException();
            }

            var type = typeof(TFeature);
            if (_features.ContainsKey(type))
            {
                _features[type] = instance;
            }
            else
            {
                _features.Add(type, instance);
            }
            throw new NotImplementedException();
        }

        public IEnumerator<KeyValuePair<Type, object>> GetEnumerator()
        {
            return _features.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _features.GetEnumerator();
        }
    }
}
